package models

import (
	"bigdevops/src/common"
	"fmt"
	"gorm.io/gorm"
	"gorm.io/gorm/clause"
	"log"
	"strings"
	"time"
)

// 采集任务 和机器的关系
// 1对多 机器只能属于1个采集任务
// 新建采集任务 就需要填入ip
// 主配置文件池
// job 对象 机器：ip+port
//
//	2 k8s 的服务发现：集群外部采集
//
// D:\nyy_work\go_path\src\github.com\prometheus\prometheus\model\rulefmt\rulefmt.go
type K8sCluster struct {
	Model         // 不用每次写ID 和 createAt了
	Name   string `json:"name" validate:"required,min=1,max=200" gorm:"uniqueIndex;type:varchar(100);comment:k8s英文集群名称，支持使用通配符*进行模糊搜索" `
	NameZh string `json:"nameZh" validate:"required,min=1,max=500" gorm:"uniqueIndex;type:varchar(100);comment:k8s中文集群名称，支持使用通配符*进行模糊搜索" `

	// D:\nyy_work\go_path\src\github.com\prometheus\prometheus\config\config.go
	// 下面是global段
	UserID uint

	CpuRequest    string `json:"cpuRequest"`
	CpuLimit      string `json:"cpuLimit"`
	MemoryRequest string `json:"memoryRequest"`
	MemoryLimit   string `json:"memoryLimit"`

	// 必备字段
	Env string `json:"env" gorm:"comment: 集群的环境：生成集群 prod stage dev rc press"`
	// 这个版本号 不需要用户填入 ,解析kubeconfig 发起 serverVersion请求
	Version string `json:"version" gorm:"comment: 集群的版本"`
	// apiServerAddr 也不需要填，解析kubeconfig就可以了
	ApiServerAddr        string `json:"apiServerAddr" gorm:"comment: apiserver地址"`
	KubeConfigContent    string `json:"kubeConfigContent" gorm:"type:text;comment: kubeconfig的内容"`
	ActionTimeoutSeconds int    `json:"actionTimeoutSeconds" gorm:"comment: 超时时间秒数"`

	Key string `json:"key" gorm:"-"` //给前端表格

	CreateUserName string `json:"createUserName" gorm:"-"`

	// \n join后的string
	LastProbeSuccess  bool              `json:"lastProbeSuccess" gorm:"-"`
	LastProbeErrorMsg string            `json:"lastProbeErrorMsg" gorm:"-"`
	LabelsFront       string            `json:"labelsFront" gorm:"-"`
	AnnotationsFront  string            `json:"annotationsFront" gorm:"-"`
	LabelsM           map[string]string `json:"labelsM" gorm:"-"`
	AnnotationsM      map[string]string `json:"annotationsM" gorm:"-"`
}

func (obj *K8sCluster) Create() error {
	return Db.Create(obj).Error

}
func (obj *K8sCluster) DeleteOne() error {

	return Db.Select(clause.Associations).Unscoped().Delete(obj).Error

}

func (obj *K8sCluster) CreateOne() error {
	return Db.Create(obj).Error

}

func (obj *K8sCluster) UpdateOne() error {
	return Db.Debug().Where("id = ?", obj.ID).Updates(obj).Error

}

func (obj *K8sCluster) SetDefaultResource() {
	obj.CpuRequest = "0.2"
	obj.MemoryRequest = "20Mi"
	obj.CpuLimit = "2"
	obj.MemoryLimit = "2Gi"
}

//func (obj *K8sCluster) ValidateRelabelConfigsYamlString() error {
//	var relabelConfigsObj []*relabel.Config
//	return yaml.Unmarshal([]byte(obj.RelabelConfigsYamlString), &relabelConfigsObj)
//
//}

func (obj *K8sCluster) GenMapFromKvs(kvs []string) map[string]string {

	labelsM := map[string]string{}
	for _, i := range kvs {
		kvs := strings.Split(i, "=")
		if len(kvs) != 2 {
			continue
		}
		k := kvs[0]
		v := kvs[1]
		labelsM[k] = v
	}
	return labelsM

}

func (obj *K8sCluster) GetGitVersionByServerVersion() (err1 error) {
	log.Printf("GetGitVersionByServerVersion开始请求")
	nowTime := time.Now()
	kConfig, kClientSet, err := common.GenK8sClientSetByKubeConfigContent(obj.KubeConfigContent)
	if err != nil {
		return err
	}

	obj.ApiServerAddr = kConfig.Host

	ctx1, cancel1 := common.GenTimeoutContext(obj.ActionTimeoutSeconds)
	defer cancel1()

	quitChan := make(chan struct{})

	go func() {
		v, err := kClientSet.ServerVersion()
		if err != nil {
			err1 = err
			close(quitChan)
			return
		}
		if v.GitVersion != "" {
			obj.Version = v.GitVersion
			close(quitChan)
		}

	}()
	defer func() {
		log.Printf("GetGitVersionByServerVersion请求耗时:[%v :%v]", obj.Name, time.Since(nowTime))
	}()

	select {
	case <-ctx1.Done():
		msg := fmt.Sprintf("ServerVersion请求达到超时时间%v ，退出", obj.ActionTimeoutSeconds)
		err1 = fmt.Errorf("%v", msg)
		fmt.Println(msg)
		return err1
		//close(quitChan)
	case <-quitChan:

	}
	return nil
}

// 0值替换 前转后
func (obj *K8sCluster) FillDefaultData() (err error) {
	if obj.ActionTimeoutSeconds == 0 {
		obj.ActionTimeoutSeconds = 3
	}

	err = obj.GetGitVersionByServerVersion()

	return err

}

func (obj *K8sCluster) FillFrontAllData() {
	dbUser, _ := GetUserById(int(obj.UserID))
	if dbUser != nil {
		obj.CreateUserName = dbUser.Username
	}

}
func GetK8sClusterAll() (objs []*K8sCluster, err error) {
	err = Db.Find(&objs).Error
	return
}

func GetK8sClusterCount() int {
	var count int64
	Db.Table("form_designs").Count(&count)
	return int(count)
}

func GetK8sClusterByLevel(level int) (objs []*K8sCluster, err error) {
	err = Db.Where("level = ?", level).Preload("OpsAdmins").Find(&objs).Error
	return
}

// select * from ecs where
func GetK8sClusterByIdsWithLimitOffset(ids []int, limit, offset int) (objs []*K8sCluster, err error) {
	err = Db.Limit(limit).Offset(offset).Find(&objs, ids).Error
	return
}

// 查询这个节点池管理的采集Job
func GetK8sClusterByPoolId(poolId uint) (objs []*K8sCluster, err error) {

	err = Db.Where("enable=1 and pool_id = ?", poolId).Find(&objs).Error
	return

}

func GetK8sClusterBySendGroupId(sendGroupId uint) (objs []*K8sCluster, err error) {

	err = Db.Where("send_group_id = ?", sendGroupId).Find(&objs).Error
	return

}

func GetK8sClusterById(id int) (*K8sCluster, error) {

	var dbObj K8sCluster
	err := Db.Where("id = ?", id).First(&dbObj).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, fmt.Errorf("K8sCluster不存在")
		}
		return nil, fmt.Errorf("数据库错误:%w", err)
	}
	return &dbObj, nil

}

func GetK8sClusterByName(name string) (*K8sCluster, error) {

	var dbObj K8sCluster
	err := Db.Where("name = ?", name).First(&dbObj).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, fmt.Errorf("K8sCluster不存在")
		}
		return nil, fmt.Errorf("数据库错误:%w", err)
	}
	return &dbObj, nil

}
